﻿namespace Atomic.Core.Security
{
    using System.Web;
    using System.Web.Mvc;

    using Atomic.Mvc;
    using Atomic.Mvc.Settings;
    using Atomic.Modules.Security;

    /// <summary>
    /// 授权。
    /// </summary>
    public class AtomicAuthorizeAttribute : AuthorizeAttribute
    {
        /// <summary>
        /// 授权程序。
        /// </summary>
        private static IAuthorizer _authorizer = null;

        /// <summary>
        /// 构造器。
        /// </summary>
        /// <param name="permissionName">权限名称。</param>
        public AtomicAuthorizeAttribute(string permissionName)
        {
            this.Permission = new Permission(permissionName, string.Empty, string.Empty);
        }

        /// <summary>
        /// 构造器。
        /// </summary>
        /// <param name="permissionName">权限信息。</param>
        public AtomicAuthorizeAttribute(Permission permission)
        {
            this.Permission = permission;
        }

        /// <summary>
        /// 权限名称。
        /// </summary>
        public Permission Permission { get; private set; }

        /// <summary>
        /// 授权程序。
        /// </summary>
        protected IAuthorizer Authorizer
        {
            get
            {
                if (_authorizer == null)
                {
                    _authorizer = AtomicContainer.Resolve<IAuthorizer>();
                }

                return _authorizer;
            }
        }

        /// <summary>
        /// 授权认证。
        /// </summary>
        /// <param name="httpContext">Http 上下文。</param>
        /// <returns>是否授权。</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool granted = this.Authorizer.Authorize(this.Permission);

            if (granted)
            {
                return true;
            }

            httpContext.Response.StatusCode = 403;

            return false;
        }

        /// <summary>
        /// 请求授权过程。
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.HttpContext.Response.StatusCode == 403)
            {
                filterContext.Result = new RedirectResult(SiteFactory.Current.Error403Page);
            }
        }
    }
}